package me.report.api.mongodb.service;

import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.gridfs.GridFSFile;
import java.io.InputStream;
import java.util.List;
import me.report.mongodb.model.Report;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

@Repository
public class MongoService {

    Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    MongoOperations mongoOperations;
    @Autowired
    GridFsTemplate gridFsTemplate;

    // Lay file tu db ----------------------------------------------------------
    public List<Report> getAll() {
        return mongoOperations.findAll(Report.class);
    }

    public Report getReportByName(String reportName) {
        return mongoOperations.findOne(new Query(Criteria.where("reportName").is(reportName)), Report.class);
    }

    public Report getReportByID(String reportId) {
        return mongoOperations.findOne(new Query(Criteria.where("reportId").is(reportId)), Report.class);
    }

    public GridFSDBFile getReportFileById(String reportIdFile) {
        return gridFsTemplate.findOne(new Query(Criteria.where("_id").is(new ObjectId(reportIdFile))));
    }
    
    public GridFSDBFile getReportFileByReportId(String reportId) {
        Report report = mongoOperations.findOne(new Query(Criteria.where("reportId").is(reportId)), Report.class);
        return gridFsTemplate.findOne(new Query(Criteria.where("_id").is(new ObjectId(report.getReportIdFile()))));
    }

    public GridFSDBFile getReportFileByFilename(String reportFileName) {
        return gridFsTemplate.findOne(new Query(Criteria.where("reportFileName").is(reportFileName)));
    }
    // Ket thuc lay file -------------------------------------------------------

    // Luu file xuong db -------------------------------------------------------
    public boolean addReport(Report report) {
        try {
            System.out.print(report.toString());
            mongoOperations.save(report);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public String saveReportFile(InputStream inputStream, String fileName) {
        GridFSFile input = gridFsTemplate.store(inputStream, fileName);
        input.save();
        return input.getId().toString();
    }
    // Ket thuc luu file -------------------------------------------------------

    // Xoa file duoi db --------------------------------------------------------
    public boolean deleteReportById(String id) {
        try {
            String idFile = mongoOperations.findOne(new Query(Criteria.where("reportId").is(id)), Report.class).getReportIdFile();
            mongoOperations.remove(new Query(Criteria.where("reportId").is(id)), Report.class);
            gridFsTemplate.delete(new Query(Criteria.where("_id").is(new ObjectId(idFile))));
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public boolean deleteReportFileByIdFile(String reportIdFile) {
        try {
            gridFsTemplate.delete(new Query(Criteria.where("_id").is(new ObjectId(reportIdFile))));
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public boolean deleteAll() {
        try {
            List<Report> list = mongoOperations.findAll(Report.class);
            for (Report report : list) {
                gridFsTemplate.delete(new Query(Criteria.where("_id").is(new ObjectId(report.getReportIdFile()))));
            }
            mongoOperations.remove(new Query(), Report.class);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    // Ket thuc xoa file -------------------------------------------------------

    // Chinh sua file duoi db --------------------------------------------------
    public boolean updateReportById(Report report) {
        try {
            Update update = new Update();
            if (StringUtils.hasText(report.getReportName())) {
                update.set("reportName", report.getReportName());
            }
            if (StringUtils.hasText(report.getReportDescription())) {
                update.set("reportDescription", report.getReportDescription());
            }
            if (StringUtils.hasText(report.getReportIdFile())) {
                update.set("reportIdFile", report.getReportIdFile());
            }

            Query query = new Query(Criteria.where("reportId").is(report.getReportId()));
            
            mongoOperations.findAndModify(query, update, Report.class);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    // Ket thuc chinh sua file -------------------------------------------------
}
